package net.stogi.dsper.back.service.impl;

import java.util.ArrayList;
import java.util.List;

import net.stogi.common.api.dto.OrderBy;
import net.stogi.common.api.exception.BusinessException;
import net.stogi.dsper.api.dto.TagDto;
import net.stogi.dsper.api.model.Tag;
import net.stogi.dsper.api.model.User;
import net.stogi.dsper.api.service.TagService;
import net.stogi.dsper.api.util.ModelToDtoConverterUtils;
import net.stogi.dsper.back.dao.TagDao;
import net.stogi.dsper.back.service.TagInternalService;
import net.stogi.dsper.back.service.UserInternalService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service("DsperBack.Service.TagService")
public class TagServiceImpl implements TagService, TagInternalService {

	private static final Logger log = LoggerFactory.getLogger(TagServiceImpl.class);

	@Autowired
	private TagDao tagDao;

	@Autowired
	private UserInternalService userService;

	@Override
	@Transactional(rollbackFor = BusinessException.class)
	public List<TagDto> listTags(Long userId) throws BusinessException {
		log.trace("listTags(): invoke: [userId = '{}']", userId);

		// Load user.
		User user = userService.getUserWithChecks(userId);

		// Load tags.
		List<Tag> tagList = tagDao.loadByUser(user, OrderBy.asc("value"));

		List<TagDto> tagDtoList = new ArrayList<TagDto>();
		// Convert tags model to DTO list.
		for (Tag tag : tagList) {
			tagDtoList.add(ModelToDtoConverterUtils.convertTagModelToDto(tag));
		}

		return tagDtoList;
	}

	@Override
	@Transactional(rollbackFor = BusinessException.class)
	public List<Long> saveTags(Long userId, List<String> tagList) throws BusinessException {
		log.trace("saveTags(): invoke: [userId = '{}', tagList = '{}']", userId, tagList);

		List<Long> tagIdList = new ArrayList<Long>();

		// Load user.
		User user = userService.getUserWithChecks(userId);

		for (String value : tagList) {
			Tag tag = new Tag(value, user);

			tagDao.save(tag);

			tagIdList.add(tag.getId());
		}

		return tagIdList;
	}

	@Override
	public Tag getTagWithChecks(Long id) throws BusinessException {
		assert id != null : "Parameter 'id' can not be null";

		// Load tag.
		Tag tag = tagDao.loadById(id, false);

		// Check tag.
		if (tag == null) {
			log.warn("Tag with given id does not exist: [tagId = '{}']", id);
			throw new BusinessException("Tag with given id does not exist: [tagId = '" + id + "']");
		}

		return tag;
	}
}
